/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package br.com.webhomesites.padrao.presenter;

import br.com.webhomesites.padrao.contracts.IComposicaoProdutoPresenter;
import br.com.webhomesites.padrao.model.*;
import br.com.webhomesites.padrao.presenter.ComposicaoProdutoPresenterActionListeners.AlterarActionListener;
import br.com.webhomesites.padrao.presenter.ComposicaoProdutoPresenterActionListeners.BuscaAvancadaActionlistener;
import br.com.webhomesites.padrao.presenter.ComposicaoProdutoPresenterActionListeners.CancelarComposicaoProdutoActionListener;
import br.com.webhomesites.padrao.presenter.ComposicaoProdutoPresenterActionListeners.CancelarItemComposicaoProdutoActionListener;
import br.com.webhomesites.padrao.presenter.ComposicaoProdutoPresenterActionListeners.ComboStateListener;
import br.com.webhomesites.padrao.presenter.ComposicaoProdutoPresenterActionListeners.InserirComposicaoProdutoActionListener;
import br.com.webhomesites.padrao.presenter.ComposicaoProdutoPresenterActionListeners.InserirItemComposicaoProdutoActionListener;
import br.com.webhomesites.padrao.presenter.ComposicaoProdutoPresenterActionListeners.RemoverItemComposicaoProdutoActionListener;
import br.com.webhomesites.padrao.presenter.ComposicaoProdutoPresenterActionListeners.SairActionListener;
import br.com.webhomesites.padrao.presenter.ComposicaoProdutoPresenterActionListeners.SalvarComposicaoProdutoActionListener;
import br.com.webhomesites.padrao.presenter.ComposicaoProdutoPresenterActionListeners.SalvarItemComposicaoProdutoActionListener;
import br.com.webhomesites.padrao.presenter.ComposicaoProdutoPresenterActionListeners.TableItensMouseListener;
import br.com.webhomesites.padrao.utils.Strategy;
import br.com.webhomesites.padrao.view.BuscarProdutoView;
import br.com.webhomesites.padrao.view.ComposicaoProdutoView;
import java.text.DecimalFormat;
import java.util.ArrayList;
import java.util.List;
import javax.swing.JOptionPane;
import org.hibernate.HibernateException;
import org.hibernate.exception.ConstraintViolationException;

/**
 *
 * @author Webhome
 */
public class ComposicaoProdutoPresenter implements IComposicaoProdutoPresenter {

    private ComposicaoProdutoModel composicaoProdutoModel;
    private ComposicaoProdutoDAO composicaoProdutoDAO;
    private ComposicaoProdutoView composicaoProdutoView;
    private ItemComposicaoProdutoModel itemComposicaoProdutoModel;
    private ItemComposicaoProdutoDAO itemComposicaoProdutoDAO;
    private ProdutoModel produtoModel;
    private ProdutoDAO produtoDAO;
    
    public final Strategy INSERT_STRATEGY = new InsertStrategy();
    public final Strategy INSERT_ITEM_STRATEGY = new InsertItemStrategy();
    public final Strategy REMOVE_ITEM_STRATEGY = new RemoveItemStrategy();
    public final Strategy UPDATE_STRATEGY = new UpdateStrategy();
    private Strategy operacao = INSERT_STRATEGY;
	
	DecimalFormat df = new DecimalFormat("###,###,###.00");
    List<ItemComposicaoProdutoModel> listaItens = new ArrayList<>();

    public ComposicaoProdutoPresenter(ComposicaoProdutoModel composicaoProdutoModel, ComposicaoProdutoDAO composicaoProdutoDAO, ComposicaoProdutoView composicaoProdutoView, ItemComposicaoProdutoModel itemComposicaoProdutoModel, ItemComposicaoProdutoDAO itemComposicaoProdutoDAO, ProdutoModel produtomodel, ProdutoDAO produtoDAO) {
        this.composicaoProdutoModel = composicaoProdutoModel;
        this.composicaoProdutoDAO = composicaoProdutoDAO;
        this.composicaoProdutoView = composicaoProdutoView;
        this.itemComposicaoProdutoModel = itemComposicaoProdutoModel;
        this.itemComposicaoProdutoDAO = itemComposicaoProdutoDAO;
        this.produtoModel = produtomodel;
        this.produtoDAO = produtoDAO;

    }

    @Override
    public void setUpViewListeners() {
         
        composicaoProdutoView.setRemoverItemComposicaoActionListener(new RemoverItemComposicaoProdutoActionListener(this));
        composicaoProdutoView.setInserirComposicaoActionListener(new InserirComposicaoProdutoActionListener(this));
        composicaoProdutoView.setAlterarActionListener(new AlterarActionListener(this));
        composicaoProdutoView.setCancelarComposicaoActionListener(new CancelarComposicaoProdutoActionListener(this));
        composicaoProdutoView.setCancelarItemComposicaoActionListener(new CancelarItemComposicaoProdutoActionListener(this));
        composicaoProdutoView.setSalvarComposicaoActionListener(new SalvarComposicaoProdutoActionListener(this));
        composicaoProdutoView.setSalvarItemComposicaoActionListener(new SalvarItemComposicaoProdutoActionListener(this));
        composicaoProdutoView.setInserirItemComposicaoActionListener(new InserirItemComposicaoProdutoActionListener(this));
        composicaoProdutoView.setBtnSairActionListener(new SairActionListener());
        composicaoProdutoView.setTableItensComposicaoMouseListener(new TableItensMouseListener(this));
        composicaoProdutoView.setBuscaAvancadaActionListener(new BuscaAvancadaActionlistener(this));

    }

    @Override
    public void updateModelComposicaoProdutoFromView() {
        try {
            produtoModel = (produtoDAO.findByDescricaoUnica(composicaoProdutoView.getDescricaoProdutoComposto()));
            composicaoProdutoModel.setId(produtoModel.getId());
            composicaoProdutoModel.setTipo(composicaoProdutoView.getTipoComposicao());
            composicaoProdutoModel.setProdutoModelComposto(produtoModel);

            if (operacao == INSERT_STRATEGY) {
                composicaoProdutoDAO.save(composicaoProdutoModel);
            }
            
        } catch (org.hibernate.exception.ConstraintViolationException e) {
            System.err.println(e);
            JOptionPane.showMessageDialog(null, "Este produto já foi composto!");
        }



    }

    @Override
    public void updateViewComposicaoFromModel() {
        if (composicaoProdutoModel != null) {
            composicaoProdutoView.setDescricaoProdutoComposto(composicaoProdutoModel.getProdutoModelComposto().getDescricao());
            composicaoProdutoView.setCodigoProdutoComposto(composicaoProdutoModel.getProdutoModelComposto().getId());
        } else {
            composicaoProdutoView.clearFields();
        }
    }

    @Override
    public void updateModelItemFromView() {
        itemComposicaoProdutoModel.setId(itemComposicaoProdutoDAO.getMaxId() + 1);
        itemComposicaoProdutoModel.setQuantidade(composicaoProdutoView.getQuantidade());
		
        produtoModel = produtoDAO.findByDescricaoUnica(composicaoProdutoView.getDescricaoProdutoAcessorio());
        itemComposicaoProdutoModel.setComposicaoProdutoModel(composicaoProdutoModel);
        itemComposicaoProdutoModel.setProdutoModel(produtoModel);
        itemComposicaoProdutoDAO.save(itemComposicaoProdutoModel);

    }

    @Override
    public void updateViewItemFromModel() {
        if (itemComposicaoProdutoModel != null) {
            composicaoProdutoView.setCodigoProdutoAcessorio(itemComposicaoProdutoModel.getProdutoModel().getId());
            composicaoProdutoView.setDescricaoProdutoAcessorio(itemComposicaoProdutoModel.getProdutoModel().getDescricao());
            composicaoProdutoView.setQuantidade(Double.toString(itemComposicaoProdutoModel.getQuantidade()));
        } else {
            composicaoProdutoView.clearFields();
        }
    }

    @Override
    public void updateViewComposicaoFromProdutoModel() {
        composicaoProdutoView.setCodigoProdutoComposto(produtoModel.getId());
        if(composicaoProdutoView.getDescricaoProdutoComposto().equals("1")) {
        composicaoProdutoView.setListaProdutoComposto(produtoDAO.findByTipo("C"));
        composicaoProdutoView.setDescricaoProdutoComposto(produtoModel.getDescricao());
        composicaoProdutoView.setItensComposicaoProdutoTableModel(new ItensComposicaoProdutoTableModel(itemComposicaoProdutoDAO.findByIdComposicaoProduto(produtoModel.getId())));
        composicaoProdutoView.refreshTableItensComposicaoProduto();
        }
        //composicaoProdutoView.setDescricaoProdutoComposto(produtoModel.getDescricao());
    }

    @Override
    public void updateViewAcessorioFromProdutoModel() {
        composicaoProdutoView.setCodigoProdutoAcessorio(produtoModel.getId());
        //composicaoProdutoView.setDescricaoProdutoComposto(produtoModel.getDescricao());
    }

    @Override
    public void updateModelFromJTable() {
        ItensComposicaoProdutoTableModel itensComposicaoProdutoTableModel = composicaoProdutoView.getItensComposicaoProdutoTableModel();

        itemComposicaoProdutoModel = itensComposicaoProdutoTableModel.getItemComposicaoProdutoModel(composicaoProdutoView.linhaSelecionadaTableItens());

        if (itemComposicaoProdutoModel != null) {
            this.updateViewItemFromModel();

            composicaoProdutoView.enableBtnRemoverItem(true);

        } else {

            composicaoProdutoView.enableBtnRemoverItem(false);
        }

        this.updateViewItemFromModel();
    }

    @Override
    public void novoComposicaoProduto() {

        composicaoProdutoModel = new ComposicaoProdutoModel();
        composicaoProdutoView.setListaProdutoComposto(produtoDAO.findByTipo("C"));
        composicaoProdutoView.setItensComposicaoProdutoTableModel(new ItensComposicaoProdutoTableModel(null));
        composicaoProdutoView.setComboDescricaoProdutoCompostoItemStateChanged(new ComboStateListener(this));

    }

    @Override
    public void novoItemComposicaoProduto() {
        itemComposicaoProdutoModel = new ItemComposicaoProdutoModel();
        composicaoProdutoView.setListaProdutoAcessorio(produtoDAO.findByTipo("A"));
        composicaoProdutoView.setComboDescricaoProdutoAcessorioItemStateChanged(new ComboStateListener(this));
    }

    @Override
    public void inserirComposicaoProduto() {
        this.updateModelComposicaoProdutoFromView();
        composicaoProdutoView.clearFields();

    }

    @Override
    public void inserirItemComposicaoProduto() {
        this.updateModelItemFromView();

        List<ItemComposicaoProdutoModel> ic = itemComposicaoProdutoDAO.findByIdComposicaoProduto(composicaoProdutoView.getCodigoProdutoComposto());

        composicaoProdutoView.setItensComposicaoProdutoTableModel(new ItensComposicaoProdutoTableModel(itemComposicaoProdutoDAO.findByIdComposicaoProduto(composicaoProdutoView.getCodigoProdutoComposto())));
        composicaoProdutoView.refreshTableItensComposicaoProduto();
        composicaoProdutoView.clearFields();
    }

    @Override
    public void alterarComposicaoProduto() {
        this.updateModelComposicaoProdutoFromView();
    }

    @Override
    public void cancelarComposicaoProduto() {
        this.updateModelComposicaoProdutoFromView();
        this.updateModelItemFromView();
    }

    @Override
    public void removerItemComposicaoProduto() {
        itemComposicaoProdutoDAO.delete(itemComposicaoProdutoModel);
        composicaoProdutoView.setItensComposicaoProdutoTableModel(new ItensComposicaoProdutoTableModel(itemComposicaoProdutoDAO.findByIdComposicaoProduto(composicaoProdutoModel.getProdutoModelComposto().getId())));
        composicaoProdutoView.refreshTableItensComposicaoProduto();

    }

    @Override
    public void habilitarEdicao(boolean arg) {
//        composicaoProdutoView.enableTxtComposicaoProdutoCodigo(arg);  
//        composicaoProdutoView.enableTxtComposicaoProdutoRazaoSocial(arg); 
//        composicaoProdutoView.enableTxtComposicaoProdutoCnpj(arg); 
//        composicaoProdutoView.enableTxtComposicaoProdutoInscriacaoEstadual(arg);  
//        composicaoProdutoView.enableTxtComposicaoProdutoEndereco(arg);
//        composicaoProdutoView.enableTxtComposicaoProdutoBairro(arg);
//        composicaoProdutoView.enableTxtComposicaoProdutoCidade(arg);
//        composicaoProdutoView.enableTxtComposicaoProdutoEstado(arg);
//        composicaoProdutoView.enableTxtComposicaoProdutoTelefone(arg);
//        composicaoProdutoView.enableTxtComposicaoProdutoEmail(arg);
//        
//        composicaoProdutoView.enableBtnCancelar(arg);
//        composicaoProdutoView.enableBtnRemover(arg);
//        composicaoProdutoView.enableBtnSalvar(arg);        
    }

    @Override
    public ComposicaoProdutoView getComposicaoProdutoView() {
        return composicaoProdutoView;
    }

    @Override
    public ComposicaoProdutoModel getComposicaoProdutoModel() {
        return composicaoProdutoModel;
    }

    @Override
    public void setComposicaoProdutoView(ComposicaoProdutoView composicaoProdutoView) {
        this.composicaoProdutoView = composicaoProdutoView;
    }

    @Override
    public void setComposicaoProdutoModel(ComposicaoProdutoModel model) {
        this.composicaoProdutoModel = model;
    }

    @Override
    public void createView() {
        //this.novoComposicaoProduto();            
        this.setUpViewListeners();

        composicaoProdutoView.removeAllitensComboProdutoComposto();
        composicaoProdutoView.removeAllitensComboProdutoAcessorio();
   
        composicaoProdutoView.setItensComposicaoProdutoTableModel(new ItensComposicaoProdutoTableModel(null));
        composicaoProdutoView.enableBtnCancelarComposicaoProduto(false);
        composicaoProdutoView.enableBtnSalvarComposicaoProduto(false);
        composicaoProdutoView.enableBtnCancelarItem(false);
        composicaoProdutoView.enableBtnSalvarItem(false);
        composicaoProdutoView.enableBtnRemoverItem(false);
        composicaoProdutoView.enableBtnInserirItem(false);

        composicaoProdutoView.packAndShow();
    }

    @Override
    public void buscaAvancada() {

        BuscarProdutoModel buscarProdutoModel = new BuscarProdutoModel();

        BuscarProdutoView buscaProdutoView = new BuscarProdutoView(javax.swing.JOptionPane.getFrameForComponent(composicaoProdutoView), true);

        BuscarProdutoPresenter buscarProdutoPresenter = new BuscarProdutoPresenter(null, null, null, this, buscaProdutoView, buscarProdutoModel);
        buscarProdutoPresenter.setBuscador(buscarProdutoPresenter.BUSCADOR_COMPOSICAO_PRODUTO_VIEW);
        buscarProdutoPresenter.createView();

    }

    public void setOperacao(Strategy operacao) {
        this.operacao = operacao;
    }

    public Strategy getOperacao() {
        return operacao;
    }

    public void setProdutoModel(ProdutoModel produtoModel) {
        this.produtoModel = produtoModel;
    }

    public ProdutoModel getProdutoModel() {
        return produtoModel;
    }

    private class InsertStrategy implements Strategy {

        @Override
        public void execute() {
            inserirComposicaoProduto();
        }
    }

    private class RemoveItemStrategy implements Strategy {

        @Override
        public void execute() {
            removerItemComposicaoProduto();
        }
    }

    private class InsertItemStrategy implements Strategy {

        @Override
        public void execute() {
            inserirItemComposicaoProduto();
        }
    }

    private class UpdateStrategy implements Strategy {

        @Override
        public void execute() {
            alterarComposicaoProduto();
        }
    }
}
